package com.polaris.live.ui.party.music

import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.RelativeLayout
import com.blankj.utilcode.util.StringUtils
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.polaris.live.R
import com.polaris.live.common.ext.setOnSingleClickListener
import com.polaris.live.common.util.ViewUtils
import com.polaris.live.databinding.WidgetMusicWindowBinding
import com.polaris.live.popup.PublicTipsPopup
import com.polaris.live.ui.party.PartyUserStateUtil
import com.polaris.live.ui.party.music.listener.MediaPlayerPlayingListener
import com.polaris.live.utils.zego.media.MediaProxy
import com.polaris.live.utils.zego.media.MusicBean
import com.polaris.live.utils.zego.media.MusicPlay
import com.polaris.live.utils.zego.media.MusicState
import im.zego.zegoexpress.constants.ZegoMediaPlayerState
import kotlin.math.abs

/**
 * MusicWindowView 音乐悬浮窗
 *
 * @author Created by 天晴 on 2024/9/19 19:59
 * @since 1.0.0
 **/
class MusicWindowView(context: Context, attrs: AttributeSet? = null) : RelativeLayout(context, attrs),
    MediaPlayerPlayingListener {

    private var isLongPress = false
    private var isDisallowInterceptRequested = false

    private val mBinding = WidgetMusicWindowBinding.inflate(LayoutInflater.from(context), this)

    private var isRetract = false
    private var isShow = false

    private var mMoreBack: (() -> Unit)? = null

    init {
        visibility = View.GONE
        MediaProxy.addListener(this)
        initListener()
    }

    fun setClickMoreListener(more: (() -> Unit)? = null) {
        mMoreBack = more
    }

    private fun closePop() {
        visibility = View.GONE
        cancelAnim()
        isShow = false
        MediaProxy.stopMusic {
        }
        mBinding.musicName.pause()
        mBinding.singerTv.pause()
    }

    private fun initListener() {
        mBinding.retractImg.setOnClickListener {
            isRetract = true
            mBinding.retractCl.visibility = View.GONE
            mBinding.musicAv.visibility = View.GONE
            mBinding.musicImg.visibility = View.VISIBLE
        }
        mBinding.musicImg.setOnClickListener {
            isRetract = false
            mBinding.retractCl.visibility = View.VISIBLE
            mBinding.musicAv.visibility = View.VISIBLE
            mBinding.musicImg.visibility = View.GONE
        }
        mBinding.closeImg.setOnClickListener {
            closePop()
        }

        mBinding.musicType.setOnClickListener {
            MediaProxy.chickMusicPlayType()
        }
        mBinding.musicProgress.setSeekToProgress {
            MediaProxy.setPlayVolume(it.toInt())
            MediaProxy.setPublishVolume(it.toInt())
            mBinding.progressTv.text = "$it%"
        }

        mBinding.musicMore.setOnSingleClickListener {
            mMoreBack?.invoke()

        }
        mBinding.musicControl.setOnSingleClickListener {
            if (!PartyUserStateUtil.inTheMaiSeat) { //不在麦位
                PublicTipsPopup.show(
                    context, null,
                    StringUtils.getString(com.polaris.live.translation.R.string.prompt),
                    StringUtils.getString(com.polaris.live.translation.R.string.you_not_seated_room),
                    StringUtils.getString(com.polaris.live.translation.R.string.go_sit_down),
                    StringUtils.getString(com.polaris.live.translation.R.string.close),
                    isViewMode = false
                )
                return@setOnSingleClickListener
            } else if (PartyUserStateUtil.siteMicStatus == 2) {
                PublicTipsPopup.show(
                    context, null,
                    StringUtils.getString(com.polaris.live.translation.R.string.prompt),
                    StringUtils.getString(com.polaris.live.translation.R.string.you_banned_playing_music),
                    "",
                    StringUtils.getString(com.polaris.live.translation.R.string.close),
                    showTop = false,
                    isViewMode = false,
                )
                return@setOnSingleClickListener
            }

            val music = MediaProxy.getCurrentMusicBean()
            music?.let {
                when (MediaProxy.getCurrentMusicState()) {
                    MusicState.UNREADY,
                    MusicState.READY,
                    MusicState.PLAY_ENDED,
                    MusicState.STOPING,
                    MusicState.FAIL,
                        -> {
                        MediaProxy.retryMusic(music)
                    }

                    MusicState.PLAYING -> {
                        MediaProxy.pause()
                    }

                    MusicState.PAUSE -> {
                        MediaProxy.startMusic(music)
                    }
                }
            }
        }
    }

    private fun showData() {
        if (!ViewUtils.isContextValid(context)) {
            return
        }

        mBinding.apply {
            val volume = MediaProxy.getPlayVolume()
            progressTv.text = "$volume%"
            mBinding.musicProgress.setMax(100)
            mBinding.musicProgress.setProgress(volume)
            mBinding.musicProgressCir.setProgress(0f)
            if (volume > 0) {
                mBinding.musicVolume.setImageResource(R.drawable.music_volume)
            } else {
                mBinding.musicVolume.setImageResource(R.drawable.music_volume_close)
            }
            MediaProxy.getCurrentMusicBean()?.let {
                musicName.setText(it.name, true)
                singerTv.setText(it.artist, true)
                Glide.with(context)
                    .load(it.getAlbumCoverFromMusicFile())
                    .placeholder(R.drawable.music_bg2)
                    .error(R.drawable.music_bg2)
                    .apply(RequestOptions.circleCropTransform())
                    .into(musicCover)
            }
            when (MediaProxy.getMusicPlayType()) {
                MusicPlay.MUSIC_SINGLE -> {
                    musicType.setImageResource(R.drawable.music_single)
                }

                MusicPlay.MUSIC_RANDOM -> {
                    musicType.setImageResource(R.drawable.music_random)
                }

                MusicPlay.MUSIC_ORDER -> {
                    musicType.setImageResource(R.drawable.music_order)
                }
            }

            when (MediaProxy.getCurrentMusicState()) {
                MusicState.UNREADY,
                MusicState.READY,
                MusicState.STOPING,
                MusicState.PAUSE,
                MusicState.PLAY_ENDED,
                MusicState.FAIL,
                    -> {
                    musicControl.setImageResource(R.drawable.music_play_white)
                }

                MusicState.PLAYING -> {
                    musicControl.setImageResource(R.drawable.music_stop2)
                }
            }

        }

    }

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        return if (isLongPress) {
            true
        } else {
            when (ev.action) {
                MotionEvent.ACTION_DOWN -> {
                    dx = ev.x
                    dy = ev.y
                    dTime = System.currentTimeMillis()
                }

                MotionEvent.ACTION_MOVE -> {
                    //长按500ms 且没有大幅度移动
                    if (System.currentTimeMillis() - dTime > 500 && maxdy < 20 && maxdx < 20) {
                        longTouch()
                    } else {
                        val ndx = abs(ev.x - dx)
                        val ndy = abs(ev.y - dy)
                        if (ndx > maxdx) {
                            maxdx = ndx
                        }
                        if (ndy > maxdy) {
                            maxdy = ndx
                        }
                    }
                }
            }
            super.onInterceptTouchEvent(ev)
        }
    }

    private fun longTouch() {
        if (!isDisallowInterceptRequested) {
            isLongPress = true
        }
    }

    private var dy = 0f
    private var dx = 0f
    private var dTime = 0L
    private var maxdy = 0f
    private var maxdx = 0f
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event == null) {
            return super.onTouchEvent(event)
        }
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                dx = event.x
                dy = event.y
                dTime = System.currentTimeMillis()
                return true
            }

            MotionEvent.ACTION_MOVE -> {
                if (isLongPress) {
                    mBinding.root.y = event.rawY - dy
                    return true
                } else {
                    //长按500ms 且没有大幅度移动
                    if (System.currentTimeMillis() - dTime > 500 && maxdy < 20 && maxdx < 20) {
                        longTouch()
                        mBinding.root.y = event.rawY - dy
                        return true
                    } else {
                        val ndx = abs(event.x - dx)
                        val ndy = abs(event.y - dy)
                        if (ndx > maxdx) {
                            maxdx = ndx
                        }
                        if (ndy > maxdy) {
                            maxdy = ndx
                        }

                        return super.onTouchEvent(event)
                    }
                }
            }

            MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
                dy = 0f
                dx = 0f
                dTime = 0L
                maxdy = 0f
                maxdx = 0f
                return if (isLongPress) {
                    isLongPress = false
                    isDisallowInterceptRequested = false
                    true
                } else {
                    super.onTouchEvent(event)
                }
            }
        }
        return super.onTouchEvent(event)
    }

    override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {
        super.requestDisallowInterceptTouchEvent(disallowIntercept)
        isDisallowInterceptRequested = disallowIntercept
    }

    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        MediaProxy.rmListener(this)
        cancelAnim()
    }

    override fun progress(millisecond: Long) {
        MediaProxy.getCurrentMusicBean()?.let {
            mBinding.musicProgressCir.setProgress(millisecond / it.duration.toFloat())
        }
    }

    override fun switchMusic(music: MusicBean) {
        if (!isShow) {
            visibility = View.VISIBLE
            isShow = true
        }
        showData()
    }

    override fun musicState(state: Int) {
        when (MediaProxy.getCurrentMusicState()) {
            MusicState.UNREADY,
            MusicState.READY,
            MusicState.STOPING,
            MusicState.PAUSE,
            MusicState.PLAY_ENDED,
            MusicState.FAIL,
                -> {
                cancelAnim()
                mBinding.musicControl.setImageResource(R.drawable.music_play_white)
            }

            MusicState.PLAYING -> {
                mBinding.musicControl.setImageResource(R.drawable.music_stop2)
                anewRun()
            }
        }
    }

    override fun musicPlayType(type: Int) {
        when (type) {
            MusicPlay.MUSIC_SINGLE -> {
                mBinding.musicType.setImageResource(R.drawable.music_single)
            }

            MusicPlay.MUSIC_RANDOM -> {
                mBinding.musicType.setImageResource(R.drawable.music_random)
            }

            MusicPlay.MUSIC_ORDER -> {
                mBinding.musicType.setImageResource(R.drawable.music_order)
            }
        }
    }

    override fun onMediaPlayerStateUpdate(state: ZegoMediaPlayerState, errorCode: Int) {
    }

    override fun onVolumeUpdate(volume: Int) {
        if (volume > 0) {
            mBinding.musicVolume.setImageResource(R.drawable.music_volume)
        } else {
            mBinding.musicVolume.setImageResource(R.drawable.music_volume_close)
        }
    }

    override fun closeMusic() {
        super.closeMusic()
        closePop()
    }

    private var rotateAnimation: ObjectAnimator? = null
    private var rotateAnimation2: ObjectAnimator? = null
    private fun anewRun() {
        cancelAnim()
        rotateAnimation = ObjectAnimator.ofFloat(mBinding.musicImg, "rotation", 0f, 360f)
        rotateAnimation?.duration = 15000
        rotateAnimation?.repeatCount = ObjectAnimator.INFINITE
        rotateAnimation?.repeatMode = ObjectAnimator.RESTART
        rotateAnimation?.interpolator = LinearInterpolator()
        rotateAnimation?.start()
        rotateAnimation2 = ObjectAnimator.ofFloat(mBinding.musicCover, "rotation", 0f, 360f)
        rotateAnimation2?.duration = 15000
        rotateAnimation2?.repeatCount = ObjectAnimator.INFINITE
        rotateAnimation2?.repeatMode = ObjectAnimator.RESTART
        rotateAnimation2?.interpolator = LinearInterpolator()
        rotateAnimation2?.start()
    }

    private fun cancelAnim() {
        rotateAnimation?.cancel()
        rotateAnimation2?.cancel()
        rotateAnimation = null
        rotateAnimation2 = null
    }
}